#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <elf.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

void DumpElf(Elf32_Ehdr *header);

int main(int argc,char **argv)
{
  
  int fd;
  void *ptMapStart;

  Elf32_Ehdr *header;
  struct stat fd_stat;
  
  fd = open("ReadElf1",O_RDONLY);
  if(fd ==  0)  
    {
      printf("Open File Error!!!");
      exit(1);
    }

  if( fstat(fd, &fd_stat) != 0 ) {
      exit(-1);
   }

  ptMapStart = mmap(NULL
                    ,sizeof(Elf32_Ehdr)
                    ,PROT_READ
                    ,MAP_SHARED
                    ,fd
                    ,0);

  if(ptMapStart < 0 )  
    {
      printf("map fail!!!!");
      exit(1);
    }

  header = (Elf32_Ehdr *)ptMapStart;

  DumpElf(header);

  printf("Num of section headers %d\n", header -> e_shnum);  

  munmap(ptMapStart
         ,sizeof(Elf32_Ehdr));
         
  
  //  printf("%d\n",sizeof(Elf32_Ehdr));
  return 0;
}

void DumpElf(Elf32_Ehdr *header)
{
  //e_type
  /*
    e_type
    ET_NONE 0 No file type
    ET_REL 1 Relocatable file
    ET_EXEC 2 Executable file
    ET_DYN 3 Shared object file
    ET_CORE 4 Core file
    ET_LOPROC 0xff00 Processor-specific
    ET_HIPROC 0xffff Processor-specific
   */
  printf("e_type\t");
  switch(header -> e_type) 
    {
    case ET_NONE:
      printf("No file type");
      break;

    case ET_REL:
      printf("Relocatable file");
      break;

    case ET_EXEC:
      printf("Executable file");
      break;

    case ET_DYN:
      printf("Shared object file");
      break;

    case ET_CORE:
      printf("Core File");
      break;
    case ET_LOPROC:
    case ET_HIPROC:
      printf("Processor - specifice");
      break;
             
    }
  printf("\n");
  //e_type end

  printf("e_machine \t");
  switch(header -> e_machine)
    {
    case ET_NONE:
      printf("No machine");
      break;

    case EM_M32:
      printf("AT&T WE 32100");
      break;

    case EM_SPARC:
      printf("SPARC\n");
      break;

    case EM_386:
      printf("Intel Architecture");
      break;

    case EM_68K:
      printf("Motorola 68000");
      break;

    case EM_88K:
      printf("Motorola 88000");
      break;

    case EM_860:
      printf("Intel 80860");
      break;
    case EM_MIPS:
      printf("MIPS RS3000 Big-Endian");
      break;
    case 10:
      printf("MIPS RS4000 Big - Endian");
      break;
    }
  printf("\n");
  //e_machine end

  //e_version start
  printf("e_version \t");
  switch(header -> e_version) 
    {
    case EV_NONE:
      printf("Invalid version");
      break;

    case EV_CURRENT:
      printf("Current version");
      break;
    }
  printf("\n");
  //e_version end

  //e_entry start
  printf("virtual address to which the system first transfers control\n");
  printf("e_entry address is \n");
  printf("e_entry = %d\n",header -> e_entry);
  printf("e_entry = 0x%x\n",header -> e_entry);
  //e_entry end

  //e_phoff start
  printf("e_phoff This member holds the program header table's file offset in bytes.\n");
  printf("e_phoff = %d\n",header -> e_phoff);
  //e_phoff end

  //e_shoff start
  printf("This member holds the section header table's file offset in bytes\n");
  printf("e_shoff =  %d\n",header -> e_shoff); 
  //e_shoff end

  //e_flags start
  printf("Eflag \n");
  printf("%d\n",header -> e_flags);
  //e_flags end

  //e_ehsize start
  printf("This member holds the ELF header's size in bytes.\n");
  printf("%d\n",header -> e_ehsize); 
  //e_ehsize end

  //e_phentsize start
  printf("e_phentsize\n");
  //  printf("This member holds the size in bytes of one entry in the file's program header table; all entries are the same size.\n");
  printf("e_phentsize = %d\n",header -> e_phentsize);
  //e_phentsize end

  //e_phnum start
  printf("e_phnum\n");
  //  printf("This member holds the number of entries in the program header table. Thus the product of e_phentsize and e_phnum gives the table's size in bytes. If a file has no program header table, e_phnum holds the value zero.\n");
  printf("e_phnum = %d\n",header -> e_phnum);  
  //e_phnum end

  //e_shentsize start
  printf("e_shentsize\n");
  //  printf("This member holds a section header's size in bytes. A section header is one entry in the section header table; all entries are the same size.\n");
  printf("e_shentsize = %d\n",header -> e_shentsize);
  //e_shentsize end

  //e_shnum start
  printf("e_shnum\n");
  //  printf("This member holds the number of entries in the section header table. Thus the product of e_shentsize and e_shnum gives the section header table's size #include bytes. If a file has no section header table, e_shnum holds the value zero.\n");
  printf("e_shnum = %d\n",header -> e_shnum); 
  //e_shnum end
  
  //e_shstrndx start
  printf("e_shstrndx\n");
  //  printf("This member holds the section header table index of the entry associated with the section name string table. If the file has no section name string table, this member holds the value SHN_UNDEF. See \"Sections\" and \"String Table\" below for more information.\n");
  printf("e_shstrndx = %d\n",header -> e_shstrndx); 
  //e_shstrndx end
}
